package org.study.seataat.order.service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.seata.core.context.RootContext;
import org.apache.seata.spring.annotation.GlobalTransactional;
import org.springframework.stereotype.Service;
import org.study.seataat.order.feign.AccountFeignClient;
import org.study.seataat.order.feign.StockFeignClient;
import org.study.seataat.order.mapper.OrderMapper;
import org.study.seataat.order.model.Order;

import java.math.BigDecimal;

/**
 * 作用描述
 *
 * @author doveylovey
 * @version v1.0.0
 * @email 1135782208@qq.com
 * @date 2024年01月25日
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
    private final AccountFeignClient accountFeignClient;
    private final StockFeignClient stockFeignClient;

    @GlobalTransactional(rollbackFor = Exception.class)
    @Override
    public void placeOrder(String userId, String commodityCode, Integer count, boolean throwEx) {
        log.info("OrderService XID = {}", RootContext.getXID());
        BigDecimal orderMoney = new BigDecimal(count).multiply(new BigDecimal(5));
        Order order = new Order()
                .setUserId(userId)
                .setCommodityCode(commodityCode)
                .setCount(count)
                .setMoney(orderMoney);
        baseMapper.insert(order);
        try {
            // 当 commodityCode="product-2" 时，模拟了一个业务异常
            stockFeignClient.deduct(commodityCode, count);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        if ("product-1".equals(commodityCode) && throwEx) {
            throw new RuntimeException("订单业务处理异常...");
        }
    }

    @GlobalTransactional(rollbackFor = Exception.class)
    @Override
    public void create(String userId, String commodityCode, Integer count) {
        BigDecimal orderMoney = new BigDecimal(count).multiply(new BigDecimal(5));
        Order order = new Order()
                .setUserId(userId)
                .setCommodityCode(commodityCode)
                .setCount(count)
                .setMoney(orderMoney);
        baseMapper.insert(order);
        accountFeignClient.reduce(userId, orderMoney);
    }
}
